package system

import (
	"context"

	"admin_template/bff/admin/hertz_gen/base"
	genSysRole "admin_template/bff/admin/hertz_gen/system/sys_role"
	"admin_template/bff/admin/internal/pkg/utils"
	"admin_template/bff/admin/internal/schema"
	"admin_template/bff/admin/internal/service"

	"github.com/cloudwego/hertz/pkg/app"
	"github.com/cloudwego/hertz/pkg/protocol/consts"
)

type RoleRepo interface {
	service.Face
	UpdateRoleRule(ctx context.Context, info *genSysRole.UpdateRuleRequest) error
	UpdateRoleApi(ctx context.Context, info *genSysRole.UpdateApiRequest) (bool, error)
}

type RoleService struct {
	*Service
}

func NewRoleService(s *Service) *RoleService {
	return &RoleService{s}
}

// Add .
// @router /v1/system/role [POST]
func (s *RoleService) Add(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.AddRequest
	s.AddFunc(s.roleRepo, &req, "roleRepo", "规则已存在", ctx, c)
}

// UpdateInfo .
// @router /v1/system/rule [PUT]
func (s *RoleService) UpdateInfo(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.UpdateRequest

	s.UpdateInfoFunc(s.roleRepo, &req, "roleRepo", "API已存在", ctx, c)
}

// Del .
// @router /v1/system/rule [DELETE]
func (s *RoleService) Del(ctx context.Context, c *app.RequestContext) {
	s.DelFunc(s.roleRepo, "roleRepo", ctx, c)
}

// UpdateState .
// @router /v1/system/rule/state [PUT]
func (s *RoleService) UpdateState(ctx context.Context, c *app.RequestContext) {
	s.UpdateStateFunc(s.roleRepo, "roleRepo", ctx, c)
}

// List .
// @router /v1/system/rule [GET]
func (s *RoleService) List(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.ListRequest
	s.ListFunc(s.roleRepo, &req, "roleRepo", ctx, c)
}

// All .
// @router /v1/system/rule/all [GET]
func (s *RoleService) All(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.AllRequest
	s.AllFunc(s.roleRepo, &req, "roleRepo", ctx, c)
}

// AllRuleByRole .
// @router /v1/system/role/rule [GET]
func (s *RoleService) AllRuleByRole(ctx context.Context, c *app.RequestContext) {

	var req genSysRole.AllRuleByRoleRequest
	ok := s.BindAndValidate(ctx, c, &req)
	if !ok {
		return
	}
	list, err := s.ruleRepo.ListByRoleID(ctx, req.RoleId)
	if err != nil {
		utils.ReplyWithErr(c,
			ctx,
			"ruleRepo ListByRoleID",
			"",
			s.CtxLogger, err)
		return
	}
	ruleList := make([]any, 0, len(list))
	for _, v := range list {
		ruleList = append(ruleList, v)
	}
	reply := schema.AllReply{
		Code: base.ErrCode_Success,
		Msg:  "获取成功",
		Data: &schema.AllData{List: ruleList},
	}
	utils.Reply(c, consts.StatusOK, &reply)

}

// AllApiByRole .
// @router /v1/system/role/api [GET]
func (s *RoleService) AllApiByRole(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.AllApiByRoleRequest
	ok := s.BindAndValidate(ctx, c, &req)
	if !ok {
		return
	}
	list, err := s.apiRepo.ListByRoleID(ctx, req.RoleId)
	if err != nil {
		utils.ReplyWithErr(c,
			ctx,
			"ruleRepo ListByRoleID",
			"",
			s.CtxLogger, err)
		return
	}
	apiList := make([]any, 0, len(list))
	for _, v := range list {
		apiList = append(apiList, v)
	}
	reply := schema.AllReply{
		Code: base.ErrCode_Success,
		Msg:  "获取成功",
		Data: &schema.AllData{List: apiList},
	}
	utils.Reply(c, consts.StatusOK, &reply)

}

// UpdateApi .
// @router /v1/system/role/api [PUT]
func (s *RoleService) UpdateApi(ctx context.Context, c *app.RequestContext) {
	var err error
	var req genSysRole.UpdateApiRequest
	ok := s.BindAndValidate(ctx, c, &req)
	if !ok {
		return
	}
	isUpdate, err := s.roleRepo.UpdateRoleApi(ctx, &req)
	if err != nil {
		utils.ReplyWithErr(c,
			ctx,
			"roleRepo UpdateRoleApi",
			"",
			s.CtxLogger, err)
		return
	}
	if isUpdate {
		apiList, err := s.apiRepo.ListByRoleID(ctx, req.Id)
		if err != nil {
			utils.ReplyWithErr(c,
				ctx,
				"apiRepo ListByRoleID",
				"",
				s.CtxLogger, err)
			return
		}
		enforcerList := make([]schema.EnforcerInfo, 0, len(apiList))
		for _, value := range apiList {
			enforcerList = append(enforcerList, schema.EnforcerInfo{
				Path:   value.Path,
				Method: value.Method,
			})
		}
		err = s.EnforcerRepo.Update(req.Id, enforcerList)
		if err != nil {
			utils.ReplyWithErr(c,
				ctx,
				"enforcerRepo Update",
				"",
				s.CtxLogger, err)
			return
		}
	}
	reply := base.BaseReply{
		Code: base.ErrCode_Success,
		Msg:  "操作成功",
	}
	utils.Reply(c, consts.StatusOK, &reply)

}

// UpdateRule .
// @router /v1/system/role/rule [PUT]
func (s *RoleService) UpdateRule(ctx context.Context, c *app.RequestContext) {
	var req genSysRole.UpdateRuleRequest
	ok := s.BindAndValidate(ctx, c, &req)
	if !ok {
		return
	}
	err := s.roleRepo.UpdateRoleRule(ctx, &req)
	if err != nil {
		utils.ReplyWithErr(c,
			ctx,
			"repo UpdateRoleRule",
			"",
			s.CtxLogger, err)
		return
	}
	reply := base.BaseReply{
		Code: base.ErrCode_Success,
		Msg:  "操作成功",
	}
	utils.Reply(c, consts.StatusOK, &reply)
}
